1. /* slfgcdl.cpp by K.Tsuru */
  2. // function ID 2000 DRADIX, BRADIX
  3. /***********************************************************************
  4. SLong and SInteger classes
  5. It provides the greatest common divisor by use of Knuth's binary method.
  6. It returns a positive value.
  7. See ReduceByPow2Rdx().
  8. Ref: The Art of Computer Programing VOLUME 2 p. 338
  9. ************************************************************************/
  10. #ifndef SN_H
  11. #include "sn.h"
  12. #endif
  13. //sub-function : While "r" is an even number it divides by the power of two.
  14. //The result is overwritten.
  15. static void DivPow2(SLong& r){
  16. if(r[0] & 1u) return;
  17. // 16 8
  18. uint pow2 = (r.Type() == r.BIN_INT) ? (8u*sizeof(ulong)-BRADIX_BITS -1u) : 2u*DFIGURES;
  19. // = 16 for BRADIX, = 8 for DRADIX, 10000^2 = (2*5)^(2*DFIGURES)
  20. ulong div = 1uL << pow2; //If the lowest two figures of "r" can be divided by this
  21. //"r" can be too.
  22. while(div >= 2uL){
  23. while( !(r.Low2() % div) ) LDivPow2(r, r, pow2);
  24. div /= 2uL; pow2--;
  25. }
  26. #ifndef NDEBUG
  27. assert(r[0] & 1); // r is odd.
  28. #endif
  29. }
  30. SLong gcdL(const SLong& x, const SLong& y){
  31. if( x.Type() != y.Type()) x.SetError(x.RADIX_ERR, "gcdL", 2000);
  32. SLong t(x.Type(), 0);
  33. if(x.IsOne() || y.IsOne()){ // x == 1 || y == 1
  34. t = 1.0; return t;
  35. }
  36. SLong u(Labs(x)), v(Labs(y));
  37. //a anterior process
  38. //It divides by a common divisor 2^b*R^p to reduce the number of dividing by two
  39. //in the next step.
  40. SLong divisor(x.Type(), 0);
  41. ReduceByPow2Rdx(u, v, &divisor);
  42. #ifndef NDEBUG
  43. assert( (u[0] & 1) || (v[0] & 1) ); // u or v must be odd.
  44. #endif
  45. if(u[0] & 1u) t = -v;
  46. else t = u;
  47. while( t.Sign(2000) ){
  48. DivPow2(t); // while( !(t[0] % 2u) ) t = LDiv2(t);
  49. if(t.Sign() > 0) u = t;
  50. else v = -t;
  51. t = u - v;
  52. }
  53. //a posterior process
  54. if(!divisor.IsOne()) u *= divisor;
  55. return u;
  56. }

slfgcdl.cpp : last modifiled at 2016/10/05 13:39:20(1,894 bytes)
created at 2017/10/07 10:26:50
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).